﻿using System;

using Ncqrs.Domain;

using TheKitchen.Commanding.Domain.Mementos;
using TheKitchen.Events;

namespace TheKitchen.Commanding.Domain
{
    public class Recipe : AggregateRootMappedByConvention
    {
        private string name;
        private string description;
        private int rating;

        /// <summary>
        /// Initializes a new instance of the <see cref="AggregateRoot"/> class.
        /// </summary>
        /// <remarks>
        /// This instance will be initialized with the <see cref="BasicGuidGenerator"/>.
        /// </remarks>
        public Recipe(Guid id, string name, string description)
        {
            ApplyEvent(new NewRecipeCreated
            {
                Id = id,
                Name = name,
                Description = description,
            });
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Recipe"/> class.
        /// </summary>
        protected Recipe()
        {
        }

        private void OnNewRecipeCreate(NewRecipeCreated evt)
        {
            Id = evt.Id;
            name = evt.Name;
            description = evt.Description;
        }
        
        /// <summary>
        /// Assigns a rating indicating the quality and deliciousnous of this recipe.
        /// </summary>
        /// <param name="rating">The rating.</param>
        public void Rate(int rating)
        {
            ApplyEvent(new RecipeRated
            {
                Rating = rating
            });  
        }

        private void OnRecipeRated(RecipeRated evt)
        {
            rating = evt.Rating;
        }

        /// <summary>
        /// Restores an object to an earlier point in time. 
        /// </summary>
        public override void RestoreFromMemento(IMemento memento)
        {
            var recipeMemento = (RecipeMemento)memento;
            name = recipeMemento.Name;
            description = recipeMemento.Description;
        }

        /// <summary>
        /// Gets an object representing all of the internal state of the object.
        /// </summary>
        public override IMemento GetMemento()
        {
            return new RecipeMemento
            {
                Name = name,
                Description = description,
                Rating = rating
            };
        }
    }
}